package com.GLM.Viewer.Map;

import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Locale;

import android.app.SearchManager;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.SearchRecentSuggestions;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;

import com.GLM.Constants.Constant;
import com.GLM.Tools.Utils.ProgressDialogHelper;
import com.GLM.Tools.Utils.ViewsUtil;
import com.GLM.Viewer.R;
import com.GLM.Viewer.FirstLogin.RegisterSecondViewActivity;
import com.GLM.Viewer.Party.CreateNewPartyLocationActivity;
import com.GLM.Viewer.Party.CreateNewPartyViewActivity;
import com.GLM.Viewer.R.string;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class MapMainActivity extends MapActivity implements OnClickListener {

	private final String TAG = "MapMainActivity";

	private MapView mMapView;
	private MapController mMapCtrl;
	private View mPopView;
	private Handler mHandler;
	
	private Drawable myLocationDrawable;
	private Drawable mylongPressDrawable;
	private MyLocationManager mLocationManager;
	private MyItemizedOverlay myLocationOverlay;
	private MyItemizedOverlay mLongPressOverlay;
	private List<Overlay> mMapOverlays;
	private OverlayItem mOverlayitem = null;
	private String mQuery;
	private GeoPoint mLocPoint;
	public Address mAddress;
	ImageButton mLoctionBtn;
	ImageButton mLayerBtn;
	ImageButton mPointwhatBtn;
	Button mSearchBtn;
	public final int MSG_VIEW_LONGPRESS = 10001;
	public final int MSG_VIEW_ADDRESSNAME = 10002;
	public final int MSG_VIEW_ADDRESSNAME_FAIL = 10004;
	public final int MSG_VIEW_LOCATIONLATLNG = 10003;
	public final int MSG_VIEW_LOCATIONLATLNG_FAIL = 10005;
	public final int MSG_VIEW_BUBBLEPOPUP_CLICK = 10006;
	private double lati;
	private double longi;
	private boolean locUse = false;
	String parentIntent;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.view_map_main);
		initButtons();

		myLocationDrawable = getResources().getDrawable(R.drawable.map_point_where);
		mylongPressDrawable = getResources().getDrawable(R.drawable.map_point_start);

		initMapView();
		initPopView();
		initHandler();
		mMapCtrl = mMapView.getController();

		myLocationOverlay = new MyItemizedOverlay(myLocationDrawable, this, mMapView, mPopView, mMapCtrl, mHandler);
		mLongPressOverlay = new MyItemizedOverlay(mylongPressDrawable, this, mMapView, mPopView, mMapCtrl, mHandler);
		mMapOverlays = mMapView.getOverlays();
		GeoPoint cityLocPoint;
		OverlayItem overlayitem;
		Intent intent = getIntent();
		Bundle bundle = intent.getExtras();
		if(bundle != null){
			parentIntent = bundle.getString("ActivityIntent");
			if(parentIntent != null){
				locUse = true;
			}
			
			double lati = intent.getDoubleExtra("lati", 39.909230);
			double lon = intent.getDoubleExtra("long", 116.397428);
				
			String storeName = bundle.getString("storeName");
			String storeAddr = bundle.getString("storeAddr");
			cityLocPoint = new GeoPoint((int)(lati*1E6), (int)(lon*1E6));
			overlayitem = new OverlayItem(cityLocPoint, storeName, storeAddr);
			
			Log.d("Intent", "intent isnot null");
			
		}
		else {// 以北京市中心为中心
			cityLocPoint = new GeoPoint(39909230, 116397428);
			overlayitem = new OverlayItem(cityLocPoint, "Hello", "Welcome to Beijing!");
			Log.d("Intent", "intent is null");
		}
		mLongPressOverlay.addOverlay(overlayitem);
		mMapOverlays.add(mLongPressOverlay);
		mMapCtrl.animateTo(cityLocPoint);
		mMapCtrl.setZoom(12);
		if(bundle == null){
			Log.d("budle", "bundle is null");
			initMyLocationManager();
		}
		if(locUse){
			Log.d("locUse", locUse+"");
			initMyLocationManager();
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	private void initButtons() {
		mLoctionBtn = (ImageButton) findViewById(R.id.map_loction);
		mLayerBtn = (ImageButton) findViewById(R.id.map_layer);
		mPointwhatBtn = (ImageButton) findViewById(R.id.map_pointwhat);
		mSearchBtn = (Button) findViewById(R.id.map_search);

		mLoctionBtn.setOnClickListener(this);
		mLayerBtn.setOnClickListener(this);
		mPointwhatBtn.setOnClickListener(this);
		mSearchBtn.setOnClickListener(this);
	}

	private void initMapView() {
		mMapView = (MapView) findViewById(R.id.map_view);
		mMapView.setBuiltInZoomControls(true);
		mMapView.setClickable(true);
	}

	private void initPopView() {
		if (null == mPopView) {
			mPopView = getLayoutInflater().inflate(R.layout.view_map_overlay_popup, null);
			mMapView.addView(mPopView, new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT, null, MapView.LayoutParams.BOTTOM_CENTER));
			mPopView.setVisibility(View.GONE);
			View bubble = mPopView.findViewById(R.id.map_bubblebtn);
			bubble.setOnClickListener(new OnClickListener() {

				public void onClick(View arg0) {
					Log.d(TAG, "点击Popup");
					navigateUpTo();
				}
			});
		}

	}

	private void initHandler() {

		mHandler = new Handler() {
			@SuppressWarnings("unchecked")
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case MSG_VIEW_LONGPRESS: {
					if (null != getLocPoint()) {
						handlerLongPressedMsg();
					}
				}
					break;
				case MSG_VIEW_ADDRESSNAME: {
					TextView desc = (TextView) mPopView.findViewById(R.id.map_bubbleText);
					desc.setText((String) msg.obj);
					mPopView.setVisibility(View.VISIBLE);
				}
					break;
				case MSG_VIEW_ADDRESSNAME_FAIL: {
					TextView desc = (TextView) mPopView.findViewById(R.id.map_bubbleText);
					desc.setText(R.string.map_address_getfail);
					mPopView.setVisibility(View.VISIBLE);
				}
					break;
				case MSG_VIEW_LOCATIONLATLNG: {
					ProgressDialogHelper.closeProgress();
					Address address = (Address) msg.obj;
					setLocPoint(new GeoPoint((int) (address.getLatitude() * 1E6), (int) (address.getLongitude() * 1E6)));
					mOverlayitem = new OverlayItem(getLocPoint(), getApplicationContext().getString(R.string.map_address_name), (address != null ? getFormattedAddress(address) : ""));
					if (mLongPressOverlay.size() > 0) {
						mLongPressOverlay.removeOverlay(0);
					}
					mPopView.setVisibility(View.GONE);
					mLongPressOverlay.addOverlay(mOverlayitem);
					mLongPressOverlay.setFocus(mOverlayitem);
					mMapOverlays.add(mLongPressOverlay);
					mMapCtrl.animateTo(getLocPoint());
					mMapView.invalidate();
				}
					break;
				case MSG_VIEW_LOCATIONLATLNG_FAIL: {
					ProgressDialogHelper.closeProgress();
					ViewsUtil.showErrorTip(MapMainActivity.this, R.string.map_address_searchfail);
				}
					break;
				case MSG_VIEW_BUBBLEPOPUP_CLICK: {
					
					navigateUpTo();
				}
					break;
				}
			}

			@SuppressWarnings("unchecked")
			private void handlerLongPressedMsg() {
				Thread thread = new Thread(new Runnable() {
					public void run() {
						String addressName = null;
						int count = 0;
						while (count < Constant.ATTEMPT_COUNT) {
							count++;
							addressName = null;
							mAddress = getLocationAddress(getLocPoint());
							if (mAddress != null) {
								addressName = getFormattedAddress(mAddress);
							}
							Log.d(TAG, "获取地址名称 -> " + addressName);
							if (addressName == null || "".equals(addressName)) {
								ViewsUtil.sleep500ms();
								continue;
							} else {
								break;
							}
						}
						Message msg = new Message();
						if (addressName == null || "".equals(addressName)) {
							msg.what = MSG_VIEW_ADDRESSNAME_FAIL;
						} else {
							msg.what = MSG_VIEW_ADDRESSNAME;
							msg.obj = addressName;
						}
						mHandler.sendMessage(msg);
					}
				});
				thread.start();
				mOverlayitem = new OverlayItem(getLocPoint(), getApplicationContext().getString(R.string.map_address_name), getApplicationContext().getString(R.string.map_address_getting));
				if (mLongPressOverlay.size() > 0) {
					mLongPressOverlay.removeOverlay(0);
				}
				mPopView.setVisibility(View.GONE);
				mLongPressOverlay.addOverlay(mOverlayitem);
				mLongPressOverlay.setFocus(mOverlayitem);
				mMapOverlays.add(mLongPressOverlay);
				mMapCtrl.animateTo(getLocPoint());
				mMapView.invalidate();
			}
		};
	}

	private void initMyLocationManager() {
		mLocationManager = MyLocationManager.getInstance(getApplicationContext(), new LocationListener() {
			public void onStatusChanged(String provider, int status, Bundle extras) {
			}

			public void onProviderEnabled(String provider) {
			}

			public void onProviderDisabled(String provider) {
			}

			public void onLocationChanged(Location location) {
				Log.d(TAG, "onLocationChanged");
				onCurrentLocation(location);
			}
		});

	}

	public void goBackButton_OnClick(View v) {
		setResult(Constant.ACTIVITY_REQUESTCODE_MAP, getIntent());
		finish();
	}

	private void navigateUpTo() {
		Intent intent = null;
		if(parentIntent.equals("RegisterSecondActivity")){
			intent = new Intent(MapMainActivity.this,RegisterSecondViewActivity.class);
		}else 
			intent = new Intent(MapMainActivity.this,CreateNewPartyViewActivity.class);
		if (mAddress != null) {
			intent.putExtra("registerAddress", (Serializable)mAddress);
			intent.putExtra(Constant.ADDRESS, getFormattedAddress(mAddress));
		}
		if(mLocPoint != null){
			double[] loc = new double[2];
			loc[0] = getLocPoint().getLatitudeE6() / 1E6;
			loc[1] = getLocPoint().getLongitudeE6() / 1E6;
			intent.putExtra(Constant.LOCATION, loc);
		
			intent.putExtra("parentIntent", "MapMainActivity");
			if(parentIntent.equals("RegisterSecondActivity")){
				startActivity(intent);
			}else{
				startActivityForResult(intent, RESULT_OK);
			}
			
			finish();
		}
	}

	private void onCurrentLocation(final Location location) {
		Log.d(TAG, "onCurrentLocationy");
		
		GeoPoint point = new GeoPoint((int) (location.getLatitude() * 1E6), (int) (location.getLongitude() * 1E6));
		mOverlayitem = new OverlayItem(point, getApplicationContext().getString(R.string.map_address_mylocation), "");
		mMapCtrl.setZoom(16);
		if (myLocationOverlay.size() > 0) {
			myLocationOverlay.removeOverlay(0);
		}
		myLocationOverlay.addOverlay(mOverlayitem);
		mMapOverlays.add(myLocationOverlay);
		mMapCtrl.animateTo(point);
		if(locUse){
			mHandler.post(new Runnable() {
				
				public void run() {
					// TODO Auto-generated method stub
					try {
						Thread.sleep(2000);
						lati = location.getLatitude();
						longi = location.getLongitude();
						Intent intent = new Intent(MapMainActivity.this,CreateNewPartyLocationActivity.class);
						intent.putExtra("lati", lati);
						intent.putExtra("longi", longi);
						setResult(RESULT_OK, intent);
						finish();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		}
	}

	private Address getLocationAddress(GeoPoint point) {
		Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
		double longitude = point.getLatitudeE6() / 1E6;
		double latitude = point.getLongitudeE6() / 1E6;
		Address address = null;
		try {
			List<Address> addresses = geoCoder.getFromLocation(longitude, latitude, 1);
			if (addresses != null) {
				address = addresses.get(0);
			}
		} catch (IOException e) {
			address = GeocoderUtil.getAddress(longitude, latitude);
			e.printStackTrace();
		}
		return address;
	}

	public static String getFormattedAddress(Address address) {
		String add;
		int maxLine = address.getMaxAddressLineIndex();
		if (maxLine >= 2) {
			add = address.getAddressLine(0) + address.getAddressLine(1);
		} else {
			add = address.getAddressLine(0);
		}
		return add;
	}

	private Address searchLocationByName(String addressName) {
		Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.CHINA);
		Address address_send = null;
		try {
			List<Address> addresses = geoCoder.getFromLocationName(addressName, 1);
			if (addresses != null) {
				address_send = addresses.get(0);
				setLocPoint(new GeoPoint((int) (address_send.getLatitude() * 1E6), (int) (address_send.getLongitude() * 1E6)));
			}
		} catch (IOException e) {
			e.printStackTrace();
			address_send = GeocoderUtil.getLocationInfo(addressName);
		}
		return address_send;
	}

	public void onClick(View v) {
		if (v.getId() == R.id.map_loction) {
			initMyLocationManager();
		} else if (v.getId() == R.id.map_search) {
			onSearchRequested();
		}
		
		
	}

	@Override
	public boolean onSearchRequested() {
		startSearch(null, false, null, false);
		return true;
	}

	// 得到搜索结果
	@Override
	public void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		mQuery = intent.getStringExtra(SearchManager.QUERY);
		SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
		suggestions.saveRecentQuery(mQuery, null);

		ProgressDialogHelper.showProgress(this, getApplicationContext().getString(R.string.map_address_searching) + mQuery);
		new Thread(new Runnable() {
			public void run() {
				Address address = null;
				int count = 0;
				while (count < Constant.ATTEMPT_COUNT) {
					count++;
					address = searchLocationByName(mQuery);
					if (address == null) {
						ViewsUtil.sleep500ms();
						continue;
					} else {
						break;
					}

				}
				Message msg = new Message();
				if (address == null) {
					msg.what = MSG_VIEW_LOCATIONLATLNG_FAIL;
				} else {
					msg.what = MSG_VIEW_LOCATIONLATLNG;
					msg.obj = address;
				}
				mHandler.sendMessage(msg);
			}
		}).start();
	}

	@Override
	public void onResume() {
		super.onResume();
	}

	@Override
	public void onPause() {
		super.onPause();
	}

	// 关闭程序也关闭定位
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		try {
			mLocationManager.destoryLocationManager();
		} catch (Exception e) {
			// TODO: handle exception
			mLocationManager = null;
		}
		
	}

	public GeoPoint getLocPoint() {
		return mLocPoint;
	}

	public void setLocPoint(GeoPoint mLocPoint) {
		this.mLocPoint = mLocPoint;
	}

	public void setLocaPointByProjectionPixels(int x, int y) {
		mLocPoint = mMapView.getProjection().fromPixels(x, y);
	}

}
